package org.budo.netty.servlet.server.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.budo.netty.servlet.server.BudoServletServer;
import org.budo.netty.servlet.server.handler.servlet.BudoServletRequest;
import org.budo.netty.servlet.util.RequestUtil;
import org.budo.netty.servlet.util.ResponseUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * @author li
 */
@Slf4j
public class DefaultServlet extends HttpServlet {
    private static final int _404 = 404;

    private static final long serialVersionUID = -7988332205625396384L;

    public static final DefaultServlet INSTANCE = new DefaultServlet();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String requestURI = request.getRequestURI();

        InputStream inputStream = request.getServletContext().getResourceAsStream(requestURI);
        if (null != inputStream) {
            ResponseUtil.write(response, inputStream);
            return;
        }

        this.handleResourceNotFound(request, response);
    }

    private void handleResourceNotFound(HttpServletRequest request, HttpServletResponse response) {
        String requestURI = request.getRequestURI();
        BudoServletRequest budoServletRequest = RequestUtil.getBudoServletRequest(request);

        if ("/".equals(requestURI)) { // index
            InputStream welcomeFile = this.findWelcomeFile(budoServletRequest);
            if (null != welcomeFile) {
                ResponseUtil.write(response, welcomeFile);
                return;
            }
        }

        this.handle404(budoServletRequest, response);
    }

    private void handle404(HttpServletRequest request, HttpServletResponse response) {
        BudoServletRequest budoServletRequest = RequestUtil.getBudoServletRequest(request);
        String requestURI = request.getRequestURI();

        response.setStatus(_404);

        BudoServletServer budoServletServer = budoServletRequest.getBudoServletHandler().getBudoServletServer();

        // find 404 conf
        Map<Integer, String> errorPages = budoServletServer.getErrorPages();
        for (Entry<Integer, String> entry : errorPages.entrySet()) {
            if (!entry.getKey().equals(_404)) {
                continue;
            }

            String _404Path = entry.getValue();
            InputStream _404InputStream = budoServletRequest.getServletContext().getResourceAsStream(_404Path);

            // 配置了404 有效
            if (null != _404InputStream) {
                ResponseUtil.write(response, _404InputStream);
            }

            // 配置的404 找不到
            log.warn("#84 request=" + request + ", _404Path=" + _404Path + ", not found");
            ResponseUtil.write(response, "<h1>404 requestURI=" + requestURI + ", 404Path=" + _404Path + " not found</h1>");
            return;
        }

        // 没有配置 404
        ResponseUtil.write(response, "<h1>404 requestURI=" + requestURI + " not found</h1>");
    }

    private InputStream findWelcomeFile(BudoServletRequest budoServletRequest) {
        List<String> welcomeFileList = budoServletRequest.getBudoServletHandler().getBudoServletServer().getWelcomeFiles();
        for (String welcomeFile : welcomeFileList) { // 配置了 欢迎页
            InputStream resource = budoServletRequest.getServletContext().getResourceAsStream(welcomeFile);
            if (null != resource) {
                return resource;
            }
        }

        // 没找到欢迎页
        return null;
    }
}